﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DcsGauges.Gui.Gauges.Interfaces;
using DcsGauges.Exceptions;
using Microsoft.Xna.Framework.Graphics;
using DcsGauges.Gui.Rendering;
using DcsGauges.DataStructures;
using Microsoft.Xna.Framework;
using DcsGauges.Data;
using DcsGauges.Shared.DataStructures;

namespace DcsGauges.Gui.Gauges.Concrete
{
    class AttitudeDirectorIndicator : GuiRenderableBase, IMultiValueGauge
    {
        private const int RENDER_TEXTURE_SIZE   = 800;
        private const string SPHERE_MODEL_PATH  = "Models/AdiSphere";

        private const float CAMERA_POS_Z        = -30.0f;
        private const float SPHERE_POS_Y        = 1.0f;

        #region Fields / Properties
        
        private float pitch                    = 0.0f;
        public float Pitch
        {
            get { return this.pitch; }
            set { this.pitch = value; }
        }

        private float roll                     = 0.0f;
        public float Roll
        {
            get { return this.roll; }
            set { this.roll = value; }
        }

        private Texture2D frameTexture          = null;
        private Texture2D indicatorTexture      = null;
        private RenderTarget2D renderTarget     = null;
        private Texture2D renderTexture         = null;
        private Model sphereModel               = null;

        #endregion


        #region Constructors

        public AttitudeDirectorIndicator(GuiRenderableBase parent, GraphicsDevice device, URect area) : base(parent, area)
        {
            this.frameTexture                   = TextureManager.GetTexture("Textures/Gauges/Backgrounds/AttitudeDirectionIndicator");
            this.indicatorTexture               = TextureManager.GetTexture("Textures/Gauges/AttitudeDirectionIndicator");

            PresentationParameters pp           = device.PresentationParameters;
            this.renderTarget                   = new RenderTarget2D(device, RENDER_TEXTURE_SIZE, RENDER_TEXTURE_SIZE, true, device.DisplayMode.Format, DepthFormat.Depth24);

            this.sphereModel                    = ModelManager.GetModel(SPHERE_MODEL_PATH);
        }

        #endregion


        #region Overrides

        public override void Render(SpriteBatch spriteBatch, GraphicsDevice device, Microsoft.Xna.Framework.Rectangle parentRect, float globalZIndex)
        {

            this.renderTexture = this.RenderAdiSphereTexture(device);

            Rectangle viewportRect              = this.CalcViewportRect(parentRect, this.frameTexture.Bounds);
            spriteBatch.Draw(this.frameTexture, viewportRect, null, Color.White, 0.0f, Vector2.Zero, SpriteEffects.None, this.NextFrontIndex(globalZIndex, 3));

            //Rectangle textureSourceRect          = this.CalcIndicatorSourcerect();

            //Vector2 origin                      = Vector2.Zero;// new Vector2(0, this.indicatorTexture.Height / 2);
            spriteBatch.Draw(this.renderTexture, viewportRect, null, Color.White, 0.0f, Vector2.Zero, SpriteEffects.None, globalZIndex);

            device.SetRenderTarget(null);
        }

        private Texture2D RenderAdiSphereTexture(GraphicsDevice device)
        {
            device.SetRenderTarget(this.renderTarget);
            device.Clear(Color.Black);

            Matrix projection                       = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45.0f), 1.0f, 0.1f, 1000.0f);
            Matrix view                             = Matrix.CreateLookAt(new Vector3(0.0f, 0.0f, CAMERA_POS_Z), Vector3.Zero, Vector3.Up); 

            foreach(var mesh in this.sphereModel.Meshes)
            {
                foreach(BasicEffect effect in mesh.Effects)
                {
                    //effect.EnableDefaultLighting();

                    effect.View         = view;
                    effect.Projection   = projection;
                    effect.World        = Matrix.CreateRotationZ((float)this.roll) * Matrix.CreateRotationX((float)this.pitch) * Matrix.CreateTranslation(0.0f, SPHERE_POS_Y, 0.0f);
                }
                mesh.Draw();
            }
            
            Texture2D rendered = (Texture2D)this.renderTarget;
            device.SetRenderTarget(null);
            return rendered;
        }


        private Rectangle CalcIndicatorSourcerect()
        {
            return new Rectangle(0, 0, this.indicatorTexture.Width, this.indicatorTexture.Height);
        }

        #endregion


        #region Interface Implementation

        public DcsProperty[] Properties
        {
#warning props missing
            get { return new DcsProperty[] {}; } // return new DataProperty[] { DataProperties.AdiPitch, DataProperties.AdiRoll }; }
        }

        public void SetValue(DcsProperty property, float value)
        {
#warning Prosp Missing
            //if(property == DataProperties.AdiPitch)
            //{
            //    this.pitch              = value;
            //}
            //else if(property == DataProperties.AdiRoll)
            //{
            //    this.roll               = value;
            //}
            //else
            //{
            //    throw new DpArgumentException("property");
            //}
        }

        public float GetValue(DcsProperty property)
        {
            return 0.0f;
#warning props missing
            //if(property == DataProperties.AdiPitch)
            //{
            //    return this.pitch;
            //}
            //else if(property == DataProperties.AdiRoll)
            //{
            //    return this.roll;
            //}
            //else
            //{
            //    throw new DpArgumentException("property");
            //}
        }

        #endregion
    }
}
